package com.interview.lock;

import java.util.concurrent.atomic.AtomicLong;

/**
 * 生产者
 * 
 * 设计要点：
 * 1. 每个生产者独立运行，不需要相互协调
 * 2. 直接向MessageQueue写入消息，无需获取锁
 * 3. 使用AtomicLong生成唯一的消息ID
 */
public class Producer implements Runnable {
    
    // 生产者ID
    private final int producerId;
    // 消息队列
    private final MessageQueue messageQueue;
    // 要生产的消息数量
    private final int messageCount;
    // 全局消息ID生成器（所有生产者共享）
    private static final AtomicLong MESSAGE_ID_GENERATOR = new AtomicLong(0);
    
    public Producer(int producerId, MessageQueue messageQueue, int messageCount) {
        this.producerId = producerId;
        this.messageQueue = messageQueue;
        this.messageCount = messageCount;
    }
    
    @Override
    public void run() {
        try {
            for (int i = 0; i < messageCount; i++) {
                // 生成唯一的消息ID
                long messageId = MESSAGE_ID_GENERATOR.incrementAndGet();
                
                // 创建消息
                Message message = new Message(
                    messageId,
                    producerId,
                    "Message-" + messageId + " from Producer-" + producerId
                );
                
                // 发送消息到队列
                // 关键：这里不需要加锁，ConcurrentLinkedQueue内部使用CAS保证线程安全
                boolean success = messageQueue.offer(message);
                
                if (!success) {
                    // 如果队列满了，可以选择重试或记录日志
                    System.err.println("Producer-" + producerId + " 发送消息失败，队列已满");
                }
                
                // 可选：添加一些延迟来模拟真实场景
                // Thread.sleep(1);
            }
            
            System.out.println("Producer-" + producerId + " 完成，共发送 " + messageCount + " 条消息");
            
        } catch (Exception e) {
            System.err.println("Producer-" + producerId + " 发生错误: " + e.getMessage());
            e.printStackTrace();
        }
    }
    
    /**
     * 重置消息ID生成器（用于测试）
     */
    public static void resetMessageIdGenerator() {
        MESSAGE_ID_GENERATOR.set(0);
    }
}

